﻿#define _CRT_SECURE_NO_WARNINGS

#include "SLDateType.h"


//初始化
void SLInit(SL* ps)//定义SL*类型的ps数据，结构体指针类型，指向结构体内数据要用->
{
	ps->arr = NULL;//在SLDateType.h头文件中知道是指针，所以初始化置空
	ps->size = ps->capacity = 0;//数据初始化等于0
}

//销毁
void SLDestroy(SL* ps)//销毁跟初始化差不多，不过要先释放空间
{
	if (ps->arr)//ps->arr!=NULL，判断不是空指针表明被使用了，就释放下
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

//打印
void SLPrint(SL* ps)
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}



//扩容
//主要目的是检查有效数据个数是否达到了阈值，如果达到了就再扩容，没有不作回应
void SLCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int NewCapacity = (ps->capacity == 0) ? 4 : 2 * ps->capacity;
		//判断如果空间容量为0就扩容为4，否则扩容为原来2倍
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, NewCapacity * sizeof(SLDataType));
		//使用realloc增加容量
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);//这个是直接退出;return是结束当前函数，并返回return后的值
		}
		ps->arr = tmp;
		ps->capacity = NewCapacity;
	}
}



//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);//assert(ps != NULL)
	SLCheckCapacity(ps);
	ps->arr[ps->size++] = x;//ps->size有效数据个数，对应下标为ps->size-1，所以插入数据对应下标应该为ps->size
	//这里使用后相当于
	//ps->arr[ps->size] = x  ，尾部插入一个数据
	//ps->size++			 ，有效数据个数+1
}

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size--);//保证有效数据个数至少有一个，即不为0
	//ps->size--	，这里把两个结合了
}

//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	int i = 0;
	for (i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//i-1>=0
	}//数据后移
	ps->arr[0] = x;//将头数据改为我们要插入的数据
	ps->size++;//有效数据个数+1
}

//头删
void SLPopFront(SL* ps)
{
	assert(ps);//传入地址不为空
	assert(ps->size);//有效数据个数不为0
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//i+1<=ps->size
	}//数据前移
	ps->size--;//有效数据个数-1
}



//指定位置之前插⼊
void SLInsert(SL* ps, int pos, SLDataType x)//位置是0~ps->size-1(pos取值范围),ps->size个数据
{											//插在0，就是arr[0]=x,其他后移;以此类推
	assert(ps);
	SLCheckCapacity(ps);

	//assert(pos >= 0 && ps < ps->size);
	//int i = 0;
	//for (i = ps->size; i > pos; i--)
	//{
	//	ps->arr[i] = ps->arr[i - 1];
	//}
	//ps->arr[pos] = x;
	//ps->size++;//下面是另一种思路

	if (pos < 0)
	{
		SLPushFront(ps, x);
	}
	else if (pos > ps->size - 1)
	{
		SLPushBack(ps, x);
	}
	else
	{
		int i = 0;
		for (i = ps->size; i > pos; i--)
		{
			ps->arr[i] = ps->arr[i - 1];
		}
		ps->arr[pos] = x;
		ps->size++;
	}
}

//指定位置删除
void SLErase(SL* ps, int pos)
{
	assert(ps);

	//assert(pos >= 0 && pos < ps->size);
	//int i = 0;
	//for (i = pos; i < ps->size; i++)
	//{
	//	ps->arr[i] = ps->arr[i + 1];
	//}
	//ps->size--;//下面是另一种思路

	if (pos < 0)
	{
		SLPopFront(ps);
	}
	else if (pos > ps->size - 1)
	{
		SLPopBack(ps);
	}
	else
	{
		int i = 0;
		for (i = pos; i < ps->size; i++)
		{
			ps->arr[i] = ps->arr[i + 1];
		}
		ps->size--;
	}
}

//查找指定数据对应的下标
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			printf("找到了\n");
			return i;
		}
	}
	printf("没有找到\n");
	return -1;
}

